package gui;

/*
   A simple program where the user can sketch curves in a variety of
   colors.  A color palette is shown on the right of the applet.
   The user can select a drawing color by clicking on a color in the
   palette.  Under the colors is a "Clear button" that the user
   can press to clear the sketch.  The user draws by clicking and
   dragging in a large white area that occupies most of the applet.
   The user's drawing is not persistant.  It is cleared if the
   applet is resized.  If it is covered, in whole or part, and
   then uncovered, the part was covered is gone.
   
   Source: http://www.l.google.com/url?sa=t&source=web&ct=res&cd=3&url=http%3A%2F%2Fmath.hws.edu%2Feck%2Fcs124%2Fjavanotes4%2Fsource%2FSimplePaint.java&ei=EcMPSv_yLMuIkQXllZCvBA&usg=AFQjCNF4LAwn3kgTze1omcOJy96gsruHMw&sig2=ZSmUYPRBRnA_1cc0eJhpPA
*/


import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.applet.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class SimplePaint extends Applet implements MouseListener, MouseMotionListener {
                
   private final static int 
               BLACK = 0,
               RED = 1,            // Some constants to make
               GREEN = 2,          // the code more readable.
               BLUE = 3,           // These numbers code for
               CYAN = 4,           // the differnet drawing colors.
               MAGENTA = 5,
               YELLOW = 6;
               
   private int currentColor = BLACK;  // The currently selected drawing color,
                                      //   coded as one of the above constants.
   

   /* The following variables are used when the user is sketching a
      curve while dragging a mouse. */

   private int prevX, prevY;     // The previous location of the mouse.
   
   private boolean isDragging;      // This is set to true while the user is dragging and drawing.
   
   private boolean isDrawing;		// This is set to true when user is drawing not erasing...
   
   private Graphics graphicsPad;  // A graphics context for the applet
                                         // that is used to draw the user's curve.
   private BufferedImage bi; // A buffered image to save the graphics context
   
   private int[][] output = {	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
		   						{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}	}; 
   private final int[][] emptyArray = {	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}	}; 
		   
   public void init() {
 
      addMouseListener(this);
      addMouseMotionListener(this);
   }
   
   
   public void clearOutputArray()
   {
	   // TODO make clearArray dynamic on size of arrray
	   for(int y=0;y<20;y++)
	   {
		   for(int x = 0; x<16 ; x++)
		   {
			   output[y][x] = -1;
		   }
	   }
	   repaint();
	   //System.out.println("Clear output array\n"+ Debug.printArray(output));
   }
	
   public void paint(Graphics g) {

      int width = getSize().width;    
      int height = getSize().height;  

      // Background of canvas
      g.setColor(Color.white);
      g.fillRect(3, 3, width - 6, height - 6);

      // canvas border
      g.setColor(Color.gray);
      g.drawRect(0, 0, width-1, height-1);

      

   } // end paint()
   
   
   public void mousePressed(MouseEvent evt) {
                 
      int x = evt.getX();   // x-coordinate where the user clicked.
      int y = evt.getY();   // y-coordinate where the user clicked.
      
      int width = getSize().width;    
      int height = getSize().height;  
      
      if (isDragging == true)  // Ignore mouse presses that occur
          return;            //    when user is already drawing a curve.
                             //    (This can happen if the user presses
                             //    two mouse buttons at the same time.)
      
   
         prevX = x;
         prevY = y;
         if (evt.getModifiers()==InputEvent.BUTTON1_MASK)
         {
        	 isDrawing = true;
         } else if (evt.getModifiers()==InputEvent.BUTTON3_MASK) {
        	 isDrawing = false;
         }
         isDragging = true;
         graphicsPad = (Graphics2D) getGraphics();
         graphicsPad.setColor(Color.black);
         
         
  	   
  	   if (isDrawing)
  	   {
  		   graphicsPad.fillRect(x-(x%20), y-(y%20), 20, 20);
  	   } else {
  		   graphicsPad.clearRect(x-(x%20), y-(y%20), 20, 20);
  	   }
  	   
       prevX = x;  // Get ready for the next line segment in the curve.
       prevY = y;
       
       if(x>=0 && x<getSize().width)
       {
    	   if (y>=0 && y<getSize().height)
    	   {
    		   if (isDrawing)
    		   {
    			   output[(y-(y%20))/20][((x-(x%20))/20)]= 1;
    		   } else {
    			   output[(y-(y%20))/20][((x-(x%20))/20)]= -1;
    		   }
    		   
    	   }
       }
       
       //System.out.println("Drawing....\n " + Debug.printArray(output));


      
   } 
   

   public void mouseReleased(MouseEvent evt) {

       if (isDragging == false)
          return;  // Nothing to do because the user isn't drawing.

       isDragging = false;
    
       
       //
       // TODO: grab data and parse it through after confirmation
       //
       
       
   }
   

   public void mouseDragged(MouseEvent evt) {


       if (isDragging == false)
          return;  // Nothing to do because the user isn't drawing.
          
       int x = evt.getX();   // x-coordinate of mouse.
       int y = evt.getY();   // y=coordinate of mouse.
       

       //if(((x-10)%20)<20 && ((y-10)%20)<20)
       {
    	   
    	   if (isDrawing)
    	   {
    		   graphicsPad.fillRect(x-(x%20), y-(y%20), 20, 20);
    	   } else {
    		   graphicsPad.clearRect(x-(x%20), y-(y%20), 20, 20);
    	   }
    	   
	       prevX = x;  // Get ready for the next line segment in the curve.
	       prevY = y;
	       
	       if(x>=0 && x<getSize().width)
	       {
	    	   if (y>=0 && y<getSize().height)
	    	   {
	    		   if (isDrawing)
	    		   {
	    			   output[(y-(y%20))/20][((x-(x%20))/20)]= 1;
	    		   } else {
	    			   output[(y-(y%20))/20][((x-(x%20))/20)]= -1;
	    		   }
	    		   
	    	   }
	       }
	       
	       //System.out.println("Drawing....\n " + Debug.printArray(output));
       }
       

   } 
   

   public void mouseEntered(MouseEvent evt) { }   
   public void mouseExited(MouseEvent evt) { }    //    (Required by the MouseListener
   public void mouseClicked(MouseEvent evt) { }   //    and MouseMotionListener
   													// interfaces).
   public void mouseMoved(MouseEvent evt) { }     
  
   public int[][] getOutput()
   {
	   return output;  
   }
   
   public void setOutput(int[][] input)
   {
	   output = input;
	   
	   //System.out.println("Loading Array: "+Debug.printArray(output));
	   
	   int xOffset = 0, xValue = 0, yValue = 0, increment = 20;
	   
	   // Clear graphics pad
       graphicsPad = (Graphics2D) getGraphics();
       graphicsPad.setColor(Color.black);
	   graphicsPad.clearRect(1,1,318, 398);
	   
	   // draw graphics pad
	   for(int[] y: output)
	   {
		   for(int x: y)
		   {
			   if(x == 1)
			   {
			       graphicsPad = (Graphics2D) getGraphics();
			       graphicsPad.setColor(Color.black);
				   graphicsPad.fillRect(xValue, yValue, 20, 20);
				   
			   }
			   xValue += increment;
		   }
		   xValue = xOffset;
		   yValue += increment;
	   }
	   
   }


   public void addRandomNoise() {
	   int[][] newOutput = output;
	   
	   double noiseThreshold = 0.97; // number between 0 and 1 to adjust how much noise to introduce...

	   //System.out.println("Noise Output\t" + Debug.printArray(newOutput));
	   for(int y=0;y<20;y++)
	   {
		   for(int x = 0; x<16 ; x++)
		   {
			   double random = Math.random();
				  
			   if (newOutput[y][x]==-1 && random>noiseThreshold)
			   {
				   //System.out.println("Random number\t" + random );
				  newOutput[y][x] = 1;
			   }
		   }
	   }

	   
	   setOutput(newOutput);
	
	}
}
